import { EnumBetResult, EnumBjlResult } from "@/models/enums/EnumBjlResult";
import { IMoneyStrategy } from "../IMoneyStrategy";
import { RecmInfo, RoundInfo } from "../ExecutePlan";
import { BossRabbitMoneyStrategy, IBossRabbitMoneyStrategyOption } from "./BossRabitMoneyStrategy";

export interface IBossMoneyStrategyV2Option extends IBossRabbitMoneyStrategyOption {
    reverse: boolean;
    failCount: number;
    reverseCount?: number;
}
export class BossMoneyStrategyV2 extends BossRabbitMoneyStrategy implements IMoneyStrategy {
    option: IBossMoneyStrategyV2Option;
    reverse: boolean = false;
    reverseCount: number = 2;
    running: boolean = true;
    recmV: EnumBjlResult = EnumBjlResult.U;
    recmMoney: number = 0;
    betCount11: number = 0;
    constructor(name: string, option?: IBossMoneyStrategyV2Option | null) {
        super(name, option)
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                reverse: false,
                failCount: 2,
                baseMoney: 100,
                winStep: 1,
                failStep: -1,
                prevMoney: 0,
                currentMoney: 100,
                reverseCount: 2
            };
        }

        this.resetStrategy();
    }
    showMoney(): [EnumBjlResult, number] {
        let [recmV, recmMoney] = super.showMoney();
        if (recmMoney > (this.option.maxMoney ?? this.currentMoney)) {
            recmMoney = this.option.maxMoney ?? this.currentMoney;
        }
        return [this.recmV, recmMoney];
    }
    resetRecm(): void {
    }
    resetStrategy(): void {
        this.reverse = this.option.reverse;
        this.reverseCount = this.option.reverseCount ?? 2;
        this.running = true;
        this.recmMoney = 0;
        this.recmV = EnumBjlResult.U;
        this.betCount11 = 0;
        super.resetStrategy();
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let betCount = this.betCount11;
        let [precmV, precmMoney] = super.toMoney(roundInfo, recmInfo, userRecm, baseMoney);
        this.betCount11 = betCount;
        let length = userRecm.summaryInfo.recmResults.length;
        let prev = userRecm.summaryInfo.recmResults[length - 1];

        if (!this.running) {

            let prePreV = userRecm.summaryInfo.recmResults[length - 2];
            let prePrePreV = userRecm.summaryInfo.recmResults[length - 3];
            let prePrePrePreV = userRecm.summaryInfo.recmResults[length - 4];
            if (prePrePrePreV == EnumBetResult.Success
                && prePreV == EnumBetResult.Fail && prePrePreV == EnumBetResult.Fail && prev == EnumBetResult.Success) {
                return [EnumBjlResult.U, 0];
            }
            else if (prePreV == EnumBetResult.Fail && prePrePreV == EnumBetResult.Fail && prev == EnumBetResult.Fail) {
                this.betCount11 = 0;
                this.reverse = true;
                this.running = true;
            }
            else if (prev == EnumBetResult.Success) {
                this.reverse = false;
                this.running = true;
            }
            else {
                return [EnumBjlResult.U, 0];
            }
        }

        let recmV = userRecm.recmV;
        let recmMoney = precmMoney;
        let reverseCount = Math.abs(this.reverseCount);
        if (userRecm.summaryInfo.lfail >= reverseCount && !this.reverse) {
            if (userRecm.summaryInfo.lfail == reverseCount) {
                this.betCount11 = 0;
            }

            this.reverse = true;
        }
        else if (this.reverse && userRecm.summaryInfo.prevResult == EnumBetResult.Success && this.betCount11 == 1) {
            // this.running = false;
            // return [EnumBjlResult.U, 0];
            this.reverse = false;
        }
        else if (userRecm.summaryInfo.prevResult == EnumBetResult.Success) {
            this.reverse = false;
        }

        if (this.reverse && recmV != EnumBjlResult.U) {
            recmV = recmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;
        }

        if (recmMoney < this.baseMoney) {
            recmMoney = this.baseMoney;
        }

        this.recmMoney = recmMoney;
        this.recmV = recmV;
        if (recmMoney > (this.option.maxMoney ?? this.currentMoney) && (this.option.maxMoney ?? 0) > 0) {
            recmMoney = this.option.maxMoney ?? this.currentMoney;
        }
        if (recmV != EnumBjlResult.U) {
            this.betCount11++;
        }
        return [recmV, recmMoney];
    }

    strategyName: string;
    debugCompoenent: string = "";
    copyValue(valueObj: any): void {
        super.copyValue(valueObj);
        let obj = valueObj as BossMoneyStrategyV2;
        if (obj) {
            this.reverse = obj.reverse;
            this.reverseCount = obj.reverseCount;
            this.running = obj.running;
            this.recmMoney = obj.recmV;
            this.recmMoney = obj.recmMoney;
            this.betCount11 = obj.betCount11;
        }

    }

}

export class BossMoneyStrategyV3 extends BossMoneyStrategyV2 implements IMoneyStrategy {
    constructor(name: string, option?: IBossMoneyStrategyV2Option | null) {
        super(name, option)
    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let betCount = this.betCount11;
        let reverse = this.reverse;
        let [precmV, precmMoney] = super.toMoney(roundInfo, recmInfo, userRecm, baseMoney);
        this.reverse = reverse;
        this.betCount11 = betCount;
        let length = userRecm.summaryInfo.recmResults.length;
        let prev = userRecm.summaryInfo.recmResults[length - 1];

        let recmV = userRecm.recmV;
        let recmMoney = precmMoney;
        if (this.reverseCount < 0) {
            let reverseCount = -this.reverseCount;
            if (userRecm.summaryInfo.lfail >= reverseCount && !this.reverse) {
                if (userRecm.summaryInfo.lfail == reverseCount) {
                    this.betCount11 = 0;
                }

                this.reverse = true;
            }
            else if (this.reverse && userRecm.summaryInfo.prevResult == EnumBetResult.Success && this.betCount11 == 1) {
                this.reverse = false;
            }
            else if (userRecm.summaryInfo.prevResult == EnumBetResult.Success) {
                this.reverse = false;
            }
        }
        else if (this.reverseCount > 0) {
            let reverseCount = this.reverseCount;
            if (userRecm.summaryInfo.lwin >= reverseCount && !this.reverse) {
                if (userRecm.summaryInfo.lwin == reverseCount) {
                    this.betCount11 = 0;
                }

                this.reverse = true;
            }
            else if (this.reverse && userRecm.summaryInfo.prevResult == EnumBetResult.Fail && this.betCount11 == 1) {
                this.reverse = false;
            }
            else if (userRecm.summaryInfo.prevResult == EnumBetResult.Fail) {
                this.reverse = false;
            }
        }


        if (this.reverse && recmV != EnumBjlResult.U) {
            recmV = recmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;
        }

        if (recmMoney < this.baseMoney) {
            recmMoney = this.baseMoney;
        }

        this.recmMoney = recmMoney;
        this.recmV = recmV;
        if (recmMoney > (this.option.maxMoney ?? this.currentMoney) && (this.option.maxMoney ?? 0) > 0) {
            recmMoney = this.option.maxMoney ?? this.currentMoney;
        }
        if (recmV != EnumBjlResult.U) {
            this.betCount11++;
        }
        return [recmV, recmMoney];
    }
}


